﻿using System;
using System.Collections.Generic;
 
using System.Text;
using System.Runtime.InteropServices;


namespace HDF5
{
    using hid_t = System.Int32;
    using herr_t = System.Int32;
    using hsize_t = System.UInt64;
    using hssize_t = System.Int64;
    using hunsigned = System.UInt32;

    using hbool_t = System.UInt32;
    using htri_t = System.Int32;
    using ssize_t = System.Int64;

    using haddr_t = System.UInt64;

    using uint32_t = System.UInt32;
    using uint64_t = System.UInt64;

    using H5O_msg_crt_idx_t = System.UInt32;

    using size_t = System.UInt32;

    using off_t = System.Int32;

    using H5E_major_t = System.Int32;
    using H5E_minor_t = System.Int32;

    using time_t = System.Int64;
    using H5Z_filter_t = System.Int32;  


    #region enums
    /* Types of objects in file */
    public enum H5O_type_t {
        H5O_TYPE_UNKNOWN = -1,	/* Unknown object type		*/
        H5O_TYPE_GROUP,	        /* Object is a group		*/
        H5O_TYPE_DATASET,		/* Object is a dataset		*/
        H5O_TYPE_NAMED_DATATYPE, 	/* Object is a named data type	*/
        H5O_TYPE_NTYPES             /* Number of different object types (must be last!) */
    }
    #endregion enums

    #region structs
    /* Information struct for object header metadata (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx) */
    public struct H5O_hdr_info_t {
        hunsigned version;		/* Version number of header format in file */
        hunsigned nmesgs;		/* Number of object header messages */
        hunsigned nchunks;		/* Number of object header chunks */
        hunsigned flags;             /* Object header status flags */
        struct space {
            hsize_t total;		/* Total space for storing object header in file */
            hsize_t meta;		/* Space within header for object header metadata information */
            hsize_t mesg;		/* Space within header for actual message information */
            hsize_t free;		/* Free space within object header */
        }  ;
        struct mesg{
            System.UInt64 present;	/* Flags to indicate presence of message type in header */
            System.UInt64 shared;	/* Flags to indicate message type is shared in header */
        } ;
    }  

    /* Information struct for object (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx) */
    public struct H5O_info_t {
        ulong 	fileno;		/* File number that object is located in */
        haddr_t 		addr;		/* Object address in file	*/
        H5O_type_t 		type;		/* Basic object type (group, dataset, etc.) */
        hunsigned 		rc;		/* Reference count of object    */
        time_t		atime;		/* Access time			*/
        time_t		mtime;		/* Modification time		*/
        time_t		ctime;		/* Change time			*/
        time_t		btime;		/* Birth time			*/
        hsize_t 		num_attrs;	/* # of attributes attached to object */
        H5O_hdr_info_t      hdr;            /* Object header information */
        /* Extra metadata storage for obj & attributes */
        struct meta_size {
            H5_ih_info_t   obj;             /* v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets */
            H5_ih_info_t   attr;            /* v2 B-tree & heap for attributes */
        }  ;
    }

    /* A struct that's part of the H5G_stat_t routine (deprecated) */
    public struct H5O_stat_t {
        hsize_t size;               /* Total size of object header in file */
        hsize_t free;               /* Free space within object header */
        hunsigned nmesgs;            /* Number of object header messages */
        hunsigned nchunks;           /* Number of object header chunks */
    } 

    #endregion structs

    #region delegates
    /* Prototype for H5Ovisit/H5Ovisit_by_name() operator */
    public delegate herr_t H5O_iterate_t(hid_t obj, [In][MarshalAs(UnmanagedType.LPStr)] string name, ref H5O_info_t info, IntPtr op_data);
    #endregion delegates

    public static class H5O
    {
        /* Flags for object copy (H5Ocopy) */
        public static System.UInt16 H5O_COPY_SHALLOW_HIERARCHY_FLAG = 0x0001;
        public static System.UInt16 H5O_COPY_EXPAND_SOFT_LINK_FLAG = 0x0002;   /* Expand soft links into new objects */
        public static System.UInt16 H5O_COPY_EXPAND_EXT_LINK_FLAG = 0x0004;   /* Expand external links into new objects */
        public static System.UInt16 H5O_COPY_EXPAND_REFERENCE_FLAG = 0x0008;   /* Copy objects that are pointed by references */
        public static System.UInt16 H5O_COPY_WITHOUT_ATTR_FLAG = 0x0010;   /* Copy object without copying attributes */
        public static System.UInt16 H5O_COPY_PRESERVE_NULL_FLAG = 0x0020;   /* Copy NULL messages (empty space) */
        public static System.UInt16 H5O_COPY_ALL = 0x003F;   /* All object copying flags (for internal checking) */
        
        /* Flags for shared message indexes.
         * Pass these flags in using the mesg_type_flags parameter in
         * H5P_set_shared_mesg_index.
         * (Developers: These flags correspond to object header message type IDs,
         * but we need to assign each kind of message to a different bit so that
         * one index can hold multiple types.)
         */
        public static System.UInt16 H5O_SHMESG_NONE_FLAG   = 0x0000;          /* No shared messages */
        public static System.UInt16 H5O_SHMESG_SDSPACE_FLAG = (1 << 0x0001); /* Simple Dataspace Message.  */
        public static System.UInt16 H5O_SHMESG_DTYPE_FLAG  = (1 << 0x0003); /* Datatype Message.  */
        public static System.UInt16 H5O_SHMESG_FILL_FLAG  =  (1 << 0x0005); /* Fill Value Message. */
        public static System.UInt16 H5O_SHMESG_PLINE_FLAG =  (1 << 0x000b); /* Filter pipeline message.  */
        public static System.UInt16 H5O_SHMESG_ATTR_FLAG =   (1 << 0x000c); /* Attribute Message.  */
        public static System.UInt16 H5O_SHMESG_ALL_FLAG =    (UInt16)(H5O_SHMESG_SDSPACE_FLAG | H5O_SHMESG_DTYPE_FLAG | H5O_SHMESG_FILL_FLAG | H5O_SHMESG_PLINE_FLAG | H5O_SHMESG_ATTR_FLAG);

        /* Object header status flag definitions */
        public static System.Byte  H5O_HDR_CHUNK0_SIZE   =          0x03;    /* 2-bit field indicating # of bytes to store the size of chunk 0's data */
        public static System.Byte  H5O_HDR_ATTR_CRT_ORDER_TRACKED = 0x04;    /* Attribute creation order is tracked */
        public static System.Byte  H5O_HDR_ATTR_CRT_ORDER_INDEXED = 0x08;    /* Attribute creation order has index */
        public static System.Byte  H5O_HDR_ATTR_STORE_PHASE_CHANGE = 0x10;    /* Non-default attribute storage phase change values stored */
        public static System.Byte  H5O_HDR_STORE_TIMES =            0x20;    /* Store access, modification, change & birth times for object */
        public static System.Byte H5O_HDR_ALL_FLAGS = (Byte)(H5O_HDR_CHUNK0_SIZE | H5O_HDR_ATTR_CRT_ORDER_TRACKED | H5O_HDR_ATTR_CRT_ORDER_INDEXED | H5O_HDR_ATTR_STORE_PHASE_CHANGE | H5O_HDR_STORE_TIMES);


        public static int H5O_SHMESG_MAX_NINDEXES = 8;
        public static int H5O_SHMESG_MAX_LIST_SIZE = 5000;

        #region Objects Functions
        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern hid_t H5Oopen( hid_t loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string name, hid_t lapl_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Olink( hid_t object_id, hid_t new_loc_id,[In][MarshalAs(UnmanagedType.LPStr)] string new_link_name, hid_t lcpl, hid_t lapl ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Oclose( hid_t object_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Ocopy( hid_t src_loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string src_name, hid_t dst_loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string dst_name, hid_t ocpypl_id, hid_t lcpl_id ) ;

        //[DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        //public static extern herr_t H5Ovisit( hid_t object_id, H5_index_t index_type, H5_iter_order_t order, H5O_iterate_t op, void *op_data ) ;

        //[DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        //public static extern herr_t H5Ovisit_by_name( hid_t loc_id, const char *object_name, H5_index_t index_type, H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t lapl_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Oset_comment( hid_t object_id, [In][MarshalAs(UnmanagedType.LPStr)] string comment ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Oset_comment_by_name( hid_t loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string name, [In][MarshalAs(UnmanagedType.LPStr)] string comment, hid_t lapl_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern ssize_t H5Oget_comment( hid_t object_id, StringBuilder comment, size_t bufsize ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern ssize_t H5Oget_comment_by_name( hid_t loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string name, StringBuilder comment, size_t bufsize, hid_t lapl_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Oget_info( hid_t object_id, ref H5O_info_t object_info ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Oget_info_by_name( hid_t loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string object_name, ref H5O_info_t object_info, hid_t lapl_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Oget_info_by_idx( hid_t loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string group_name, H5_index_t index_field, H5_iter_order_t order, hsize_t n, ref H5O_info_t object_info, hid_t lapl_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern hid_t H5Oopen_by_idx( hid_t loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string group_name, H5_index_t index_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern hid_t H5Oopen_by_addr( hid_t loc_id, haddr_t addr )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Oincr_refcount( hid_t object_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Odecr_refcount( hid_t object_id );

        #endregion Objects Functions
    }
}
